home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / gc / GCenum_objs.c < prev    next >
C/C++ Source or Header  |  1991-06-06  |  3KB  |  103 lines

  1. #include <xr/Threads.h>
  2. #include <xr/GCPrivate.h>
  3. #include <xr/ThreadsSchedCtl.h>
  4. #include <xr/GCenum_objs.h>
  5.  
  6. /* Priorirty of "world stopped" collection */
  7. static XR_Pri gcExclusivePriority = XR_PRI_SYS_EXCLUSIVE;
  8.  
  9. typedef struct CallBackInfoRep {
  10.     callback_fn my_fn;
  11.     XR_Pointer my_client_data;
  12.     bool got_proper_callback;
  13. } * CallBackInfo;
  14.  
  15. void XR_EnumObjsInner();
  16.  
  17. static void callback(cbi, info)
  18. CallBackInfo cbi;
  19. GC_Info info;
  20. {
  21.     if (!(info -> gci_full_collection)) return;
  22.     if (cbi -> got_proper_callback) return;
  23.     XR_EnumObjsInner(cbi -> my_fn, cbi -> my_client_data);
  24.     cbi -> got_proper_callback = TRUE;
  25. }
  26.  
  27. /* Call fn for each marked object in the heap. */
  28. void XR_EnumObjsInner(fn, client_data)
  29. callback_fn fn;
  30. XR_Pointer client_data;
  31. {
  32.     register struct hblk *hbp;    /* ptr to current heap block        */
  33.     register int word_no;    /* Number of word in block        */
  34.     register int mb;            /* mark bit of current object           */
  35.     register word *p;           /* pointer to current word in block     */
  36.     word *plim;
  37.     int sz;            /* size of objects in current block    */
  38.     struct hblk **nexthbp;      /* ptr to ptr to current heap block     */
  39.     bool is_atomic;
  40.  
  41.     hbp = (struct hblk *) GC_heapstart;
  42.     for (; ((char *)hbp) < GC_heaplim; hbp++) if (is_hblk(hbp)) {
  43.     sz = hb_sz(hbp);
  44.     if (sz < 0) {
  45.         sz = -sz;
  46.         is_atomic = TRUE;        /* this block contains atomic objs */
  47.     } else {
  48.         is_atomic = FALSE;
  49.     }
  50.  
  51.     if( sz > MAXOBJSZ ) {  /* 1 big object */
  52.         mb = mark_bit(hbp, (hbp -> hb_body) - ((word *)(hbp)));
  53.         if (mb) {
  54.             (*fn)(client_data,  (XR_Pointer)(hbp -> hb_body),
  55.                   WORDS_TO_BYTES(sz), is_atomic);
  56.         }
  57.     } else { /* small objects */
  58.         p = (word *)(hbp->hb_body);
  59.         word_no = ((word *)p) - ((word *)hbp);
  60.         plim = (word *)((((unsigned)hbp) + HBLKSIZE)
  61.                - WORDS_TO_BYTES(sz));
  62.         while( p <= plim )  {
  63.             mb = mark_bit(hbp, word_no);
  64.             if (mb) {
  65.                 (*fn)(client_data,  (XR_Pointer)p,
  66.                       WORDS_TO_BYTES(sz), is_atomic);
  67.             }
  68.             p += sz;
  69.             word_no += sz;
  70.         }
  71.     }
  72.     }    
  73. }
  74.  
  75. /* Call fn for each accessible object in the heap.  All calls are perfomed */
  76. /* with all threads not at GC priority stopped.  This does a full,         */
  77. /* stop-the-world garbage collection before the first call to fn.          */
  78. /* The function fn must be prepared to run with the world stopped.  It     */
  79. /* may not acquire monitor locks, since                      */
  80. /* another thread may have been frozen while holding a lock.           */
  81. /* Fn is run on VP 0, and thus may use the UNIX stack for temporary        */
  82. /* storage if it chooses.                           */
  83. void XR_EnumObjs(fn, client_data)
  84. callback_fn fn;
  85. XR_Pointer client_data;
  86. {
  87.     RegisterGCCallbackType oldduring;
  88.     XR_Pointer oldclientdata;
  89.     struct CallBackInfoRep my_cbi;
  90.     
  91.     XR_MonitorEntry(&GC_allocate_ml);
  92.     my_cbi.my_fn = fn;
  93.     my_cbi.my_client_data = client_data;
  94.     my_cbi.got_proper_callback = FALSE;
  95.     XR_RegisterGCCallBackDuringInner(callback,&my_cbi,
  96.                      &oldduring,&oldclientdata);
  97.     while (!my_cbi.got_proper_callback) {
  98.         GC_demand_full_and_wait();
  99.     }
  100.     XR_RegisterGCCallBackDuringInner(oldduring,oldclientdata,0,0);
  101.     XR_MonitorExit(&GC_allocate_ml);
  102. }
  103.